package com.oocl.scan.jdt.parser;

import com.oocl.scan.model.JavaClassElement;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;

public class JavaParser {

  private ASTParser astParser;

  public JavaParser() {
    astParser = ASTParser.newParser(AST.JLS8); //设置Java语言规范版本
    astParser.setKind(ASTParser.K_COMPILATION_UNIT);
    Map<String, String> compilerOptions = JavaCore.getOptions();
    compilerOptions.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8); //设置Java语言版本
    compilerOptions.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8);
    compilerOptions.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
    astParser.setCompilerOptions(compilerOptions); //设置编译选项
  }

  public JavaClassElement buildClass(String sourceCode) {
    astParser.setSource(sourceCode.toCharArray());
    CompilationUnit compilationUnit = (CompilationUnit) astParser.createAST(null);
    JavaClassElement javaClassElement = new JavaClassElement();
    if(compilationUnit.getPackage() == null){
      return null;
    }
    javaClassElement.setPackageDeclaration(compilationUnit.getPackage());
    javaClassElement.setImports(compilationUnit.imports());
    List types = compilationUnit.types();
    if (types.size() > 0 && types.get(0) instanceof TypeDeclaration) {
      TypeDeclaration typeDec = (TypeDeclaration) types.get(0);
      javaClassElement.setTypeDeclaration(typeDec);
      javaClassElement.setClassName(typeDec.getName().getIdentifier());
      FieldDeclaration[] fieldDeclaration = typeDec.getFields();
      MethodDeclaration[] methodDeclaration = typeDec.getMethods();
      if (typeDec.getSuperclassType() != null) {
        javaClassElement.setParent(typeDec.getSuperclassType().toString());
      }
      javaClassElement.setImplementList(typeDec.superInterfaceTypes());
      javaClassElement.setFieldDeclarationList(Arrays.asList(fieldDeclaration));
      javaClassElement.setMethodDeclarationList(Arrays.asList(methodDeclaration));
      return javaClassElement;
    }
    return null;
  }

  public JavaClassElement buildClass(String resource, String moduleName, String domainName) {
    JavaClassElement javaClassElement = buildClass(resource);
    if (javaClassElement == null) {
      return null;
    }
    if (moduleName != null) {
      javaClassElement.setModuleName(moduleName);
    }
    if (domainName != null) {
      javaClassElement.setDomainName(domainName);
    }
    return javaClassElement;
  }
}
